<template>
  <div class="gantt-chart bg-white rounded-xl shadow-md overflow-hidden">
    <!-- 时间范围统计 -->
    <div class="p-4 border-b border-gray-200 bg-gray-50">
      <div class="flex flex-wrap gap-x-6 gap-y-2 text-sm">
        <div>
          <span class="font-medium text-gray-700">时间范围：</span>
          <span class="text-gray-600">{{ formatFullDate(minDate) }} - {{ formatFullDate(maxDate) }}</span>
        </div>
        <div>
          <span class="font-medium text-gray-700">总天数：</span>
          <span class="text-gray-600">{{ totalDays }}天</span>
        </div>
        <div v-if="isTodayInRange">
          <span class="font-medium text-gray-700">当前日期：</span>
          <span class="text-red-500">{{ formatFullDate(today) }}</span>
        </div>
      </div>
    </div>

    <!-- 甘特图内容 -->
    <div class="overflow-x-auto">
      <div class="min-w-[900px]">
        <!-- 任务名称头部 -->
        <div class="flex border-b border-gray-200">
          <div class="w-48 bg-gray-50 p-3 font-medium border-r border-gray-200 " >任务名称</div>
          <div class="flex-1 bg-gray-50 relative">
            <!-- 头部当前日期线（带标签） -->
            <div v-if="isTodayInRange"
                 class="absolute top-0 bottom-0 w-0.5 bg-red-500 z-10"
                 :style="{ left: `${getTodayPosition()}%` }">
              <div class="absolute -translate-x-1/2 top-1 bg-red-500 text-white text-xs px-1.5 py-0.5 rounded whitespace-nowrap">
                今天 {{ formatShortDate(today) }}
              </div>
            </div>
          </div>
        </div>

        <!-- 任务行 -->
        <div
            v-for="task in tasks"
            :key="task.id"
            class="flex items-center border-b border-gray-200 hover:bg-gray-50 transition-colors"
        >
          <!-- 任务名称 -->
          <div class="w-48 p-3 font-medium border-r border-gray-200 bg-white">
            <div class="flex items-center">
              <span class="inline-block w-2 h-2 rounded-full mr-2" :style="{ backgroundColor: getTaskColor(task.id) }"></span>
              <span>{{ task.name }}</span>
            </div>
          </div>

          <!-- 任务条 -->
          <div class="flex-1 relative h-16" >
            <!-- 当前日期竖线（不带标签） -->
            <div v-if="isTodayInRange"
                 class="absolute top-0 bottom-0 w-0.5 bg-red-500 z-10"
                 :style="{ left: `${getTodayPosition()}%` }">
            </div>

            <!-- 任务条 -->
            <div
                class="absolute h-8 top-4 rounded-md flex items-center justify-center text-white text-xs font-medium cursor-pointer shadow-sm hover:shadow-md transition-shadow z-0 px-2"
                :style="{
                left: `${getTaskLeft(task)}%`,
                width: `${getTaskWidth(task)}%`,
                backgroundColor: getTaskColor(task.id)
              }"
                @click="toggleTooltip(task, $event)"
            >
              <span class="truncate">{{ task.name }}</span>
            </div>

            <!-- 开始时间标记 -->
            <div
                class="absolute text-xs text-gray-600 whitespace-nowrap"
                :style="{ left: `${getTaskLeft(task)}%`, top: '2px', transform: 'translateX(-100%)' }"
            >
              {{ formatShortDate(task.time[0]) }}
            </div>

            <!-- 结束时间标记 -->
            <div
                class="absolute text-xs text-gray-600 whitespace-nowrap"
                :style="{ left: `${getTaskLeft(task) + getTaskWidth(task)}%`, top: '2px', transform: 'translateX(-1%)' }"
            >
              {{ formatShortDate(task.time[1]) }}
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 工具提示 -->
    <div
        v-if="tooltipVisible"
        class="fixed bg-white p-3 rounded-md shadow-lg z-50 border border-gray-200 text-sm w-56"
        :style="{
        left: `${tooltipX}px`,
        top: `${tooltipY}px`,
        transform: 'translate(-50%, -100%)',
        marginTop: '-8px'
      }"
    >
      <div class="font-medium mb-1">{{ tooltipTask.name }}</div>
      <div class="text-xs text-gray-500 space-y-1">
        <div>开始: {{ tooltipTask.time[0] }}</div>
        <div>结束: {{ tooltipTask.time[1] }}</div>
        <div>持续: {{ getTaskDuration(tooltipTask) }}天</div>
      </div>
      <!-- 三角形指示器 -->
      <div class="absolute -bottom-4 left-1/2 transform -translate-x-1/2 w-0 h-0 border-l-8 border-r-8 border-t-8 border-l-transparent border-r-transparent border-t-gray-200"></div>
      <div class="absolute -bottom-3 left-1/2 transform -translate-x-1/2 w-0 h-0 border-l-7 border-r-7 border-t-7 border-l-transparent border-r-transparent border-t-white"></div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, watch } from 'vue'

// 接收外部传入的数据
const props = defineProps({
  tasks: {
    type: Array,
    required: true,
    default: () => []
  }
})

// 状态管理
const tooltipVisible = ref(false)
const tooltipTask = ref(null)
const tooltipX = ref(0)
const tooltipY = ref(0)
const calendarDates = ref([])
const minDate = ref(null)
const maxDate = ref(null)
const totalDays = ref(0)
const today = ref(new Date())
const isTodayInRange = ref(false)
// 边距百分比（左右各预留1%的空间）
const marginPercentage = 4;

// 计算最早和最晚日期及总天数
const calculateDateRange = () => {
  if (!props.tasks || props.tasks.length === 0) return

  // 提取所有日期并转换为 Date 对象
  const allDates = props.tasks.flatMap(task =>
      task.time.map(date => new Date(date))
  )

  // 计算最早和最晚日期
  minDate.value = new Date(Math.min(...allDates))
  maxDate.value = new Date(Math.max(...allDates))

  // 计算总天数
  totalDays.value = Math.ceil((maxDate.value - minDate.value) / (1000 * 60 * 60 * 24)) + 1

  // 扩展日期范围，使甘特图更美观
  const extendedMin = new Date(minDate.value)
  const extendedMax = new Date(maxDate.value)
  extendedMin.setDate(extendedMin.getDate() - 2)
  extendedMax.setDate(extendedMax.getDate() + 2)

  // 生成日期数组
  const dates = []
  const currentDate = new Date(extendedMin)

  while (currentDate <= extendedMax) {
    dates.push(new Date(currentDate))
    currentDate.setDate(currentDate.getDate() + 1)
  }

  calendarDates.value = dates
  updateTodayStatus()
}

// 更新当前日期状态
const updateTodayStatus = () => {
  // 重置为当天（去除时间部分）
  today.value = new Date()
  today.value.setHours(0, 0, 0, 0)

  // 检查今天是否在显示范围内
  isTodayInRange.value = today.value >= minDate.value && today.value <= maxDate.value
}

// 计算任务条位置和宽度（增加边距处理）
const getTaskLeft = (task) => {
  const taskStart = new Date(task.time[0])
  const offset = (taskStart - minDate.value) / (1000 * 60 * 60 * 24)
  const totalDisplayDays = (maxDate.value - minDate.value) / (1000 * 60 * 60 * 24)

  // 计算基础百分比，加上左边距，同时调整总可用空间比例
  const basePercent = (offset / totalDisplayDays) * 100;
  const availablePercent = 100 - (marginPercentage * 2);

  return marginPercentage + (basePercent * availablePercent / 100);
}

const getTaskWidth = (task) => {
  const taskStart = new Date(task.time[0])
  const taskEnd = new Date(task.time[1])
  const duration = (taskEnd - taskStart) / (1000 * 60 * 60 * 24)
  const totalDisplayDays = (maxDate.value - minDate.value) / (1000 * 60 * 60 * 24)

  // 计算宽度百分比时考虑可用空间（扣除两边边距）
  const availablePercent = 100 - (marginPercentage * 2);
  let widthPercent = (duration / totalDisplayDays) * availablePercent;

  // 确保任务条有最小宽度，同时不超过可用空间
  const minWidth = 2;
  const maxWidth = availablePercent;
  return Math.min(Math.max(widthPercent, minWidth), maxWidth);
}

// 计算当前日期位置（同步调整边距影响）
const getTodayPosition = () => {
  if (!isTodayInRange.value) return 0

  const offset = (today.value - minDate.value) / (1000 * 60 * 60 * 24)
  const totalDisplayDays = (maxDate.value - minDate.value) / (1000 * 60 * 60 * 24)

  const basePercent = (offset / totalDisplayDays) * 100;
  const availablePercent = 100 - (marginPercentage * 2);

  return marginPercentage + (basePercent * availablePercent / 100) + 0.6;
}

// 工具函数
const formatShortDate = (date) => {
  if (!date) return ''
  const d = typeof date === 'string' ? new Date(date) : date
  return `${d.getMonth() + 1}/${d.getDate()}`
}

const formatFullDate = (date) => {
  if (!date) return ''
  return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`
}

const getTaskDuration = (task) => {
  const start = new Date(task.time[0])
  const end = new Date(task.time[1])
  return Math.ceil((end - start) / (1000 * 60 * 60 * 24)) + 1
}

// 任务颜色
const getTaskColor = (id) => {
  const colors = [
    '#409EFF', // 蓝色
    '#67C23A', // 绿色
    '#E6A23C', // 黄色
    '#F56C6C', // 红色
    '#909399', // 灰色
    '#8E44AD', // 紫色
    '#36CBCB', // 青色
    '#F08080', // 珊瑚红
    '#FF7F50', // 橙红色
    '#BA55D3'  // 紫罗兰色
  ]
  return colors[(id - 1) % colors.length]
}

// 交互控制
const toggleTooltip = (task, event) => {
  if (tooltipVisible.value && tooltipTask.value?.id === task.id) {
    tooltipVisible.value = false
    return
  }

  // 计算提示框位置（显示在点击位置上方）
  tooltipX.value = event.clientX
  tooltipY.value = event.clientY
  tooltipTask.value = task
  tooltipVisible.value = true
}

// 点击其他区域关闭提示框
document.addEventListener('click', (e) => {
  const ganttElement = document.querySelector('.gantt-chart')
  if (ganttElement && !ganttElement.contains(e.target.closest('.cursor-pointer, .gantt-chart > div:last-child'))) {
    tooltipVisible.value = false
  }
})

// 监听任务数据变化
watch(() => props.tasks, () => {
  calculateDateRange()
}, { immediate: true })

onMounted(() => {
  calculateDateRange()
  // 每天更新一次当前日期
  setInterval(updateTodayStatus, 86400000)
})
</script>

<style scoped>
.gantt-chart {
  font-family: 'Inter', sans-serif;
}

/* 自定义滚动条样式 */
::-webkit-scrollbar {
  height: 8px;
  width: 8px;
}

::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 4px;
}

::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}
</style>
